﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;

namespace BayNexususer.XMLModel
{
    public class XmlUtilTool
    {
         /// <summary>  
        /// 将字符串（符合xml格式）转换为XmlDocument  
        /// </summary>  
        /// <param name="xmlString">XML格式字符串</param>  
        /// <returns></returns>  
        public static XmlDocument ConvertStringToXmlDocument(string xmlString)
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml(xmlString);
            return document;
        }  
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="o"></param>
        /// <param name="encoding"></param>
        /// <param name="removeXmlns">true,不生成xmlns</param>
        /// <param name="OmitXmlDeclaration">忽略 类似&lt;?xml version='1.0' encoding='utf-8'?&gt;</param>
        private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding, bool removeXmlns, bool OmitXmlDeclaration)
        {
            if (o == null)
                throw new ArgumentNullException("对象为空");
            if (encoding == null)
                throw new ArgumentNullException("未指定编码");
            XmlSerializer serializer = null;
            XmlAttributes attrs = new XmlAttributes();
            attrs.XmlIgnore = true;//忽略
            XmlAttributeOverrides xOver = new XmlAttributeOverrides();
            xOver.Add(o.GetType(), "Drivers", attrs);
            serializer = new XmlSerializer(o.GetType(), xOver);
            if (serializer == null)
            {
                serializer = new XmlSerializer(o.GetType());
            }
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.NewLineChars = "\r\n";
            settings.Encoding = encoding;
            settings.IndentChars = "    ";
            settings.OmitXmlDeclaration = OmitXmlDeclaration;//true:忽略 <?xml version='1.0' encoding='utf-8'?>
            using (XmlWriter writer = XmlWriter.Create(stream, settings))
            {
                if (removeXmlns)//true,不生成xmlns
                {
                    XmlSerializerNamespaces _namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { new XmlQualifiedName(string.Empty, string.Empty) });
                    serializer.Serialize(writer, o, _namespaces);
                }
                else
                {
                    serializer.Serialize(writer, o);
                }
                writer.Close();
            }
        }

        /// <summary>
        /// 将一个对象序列化为XML字符串
        /// </summary>
        /// <param name="o">要序列化的对象</param>
        /// <param name="encoding">编码方式</param>
        /// <param name="removeXmlns">是否移除根节点的命名空间,true 移除 false 保留</param>
        /// <param name="OmitXmlDeclaration">忽略 类似&lt;?xml version='1.0' encoding='utf-8'?&gt;</param>
        /// <returns>序列化产生的XML字符串</returns>
        public static string XmlSerialize(object o, Encoding encoding, bool removeXmlns, bool OmitXmlDeclaration)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                XmlSerializeInternal(stream, o, encoding, removeXmlns, OmitXmlDeclaration);
                stream.Position = 0;
                using (StreamReader reader = new StreamReader(stream, encoding))
                {
                    if (OmitXmlDeclaration)
                    {
                        return "<?xml version='1.0' encoding='GBK'?>" + Environment.NewLine + reader.ReadToEnd();
                    }
                    else
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
        }
        /// <summary>
        /// 将一个对象按XML序列化的方式写入到一个文件
        /// </summary>
        /// <param name="xmlString">要序列化的xml文本</param>
        /// <param name="path">保存文件路径</param>
        /// <param name="filename">生成的xml文件名</param>
        public static void XmlSerializeToFile(string xmlString, string path, string filename)
        {
            if (string.IsNullOrEmpty(xmlString))
                throw new ArgumentNullException("xmlString");
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path");
            if (string.IsNullOrEmpty(filename))
                throw new ArgumentNullException("filename");
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xmlString);
            xmlDoc.Save(System.IO.Path.Combine(path, filename));
        }


        /// <summary>
        /// 将自定义对象序列化为XML字符串
        /// </summary>
        /// <param name="myObject">自定义对象实体</param>
        /// <returns>序列化后的XML字符串</returns>
        public static string SerializeToXml<T>(T myObject)
        {
            if (myObject != null)
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));

                MemoryStream stream = new MemoryStream();
                XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
                writer.Formatting = Formatting.None;//缩进
                xs.Serialize(writer, myObject);

                stream.Position = 0;
                StringBuilder sb = new StringBuilder();
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        sb.Append(line);
                    }
                    reader.Close();
                }
                writer.Close();
                return sb.ToString();
            }
            return string.Empty;
        }

        /// <summary>
        /// 将XML字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="xml">XML字符</param>
        /// <returns></returns>
        public static T DeserializeToObject<T>(string xml)
        {
            T myObject;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            StringReader reader = new StringReader(xml);
            myObject = (T)serializer.Deserialize(reader);
            reader.Close();
            return myObject;
        }
    }
}